package com.sinovatech.ologger.actionlog.entity;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sinovatech.ologger.actionlog.vo.OperationLogVO;
import com.sinovatech.ologger.core.web.jsonplugin.JSONException;
import com.sinovatech.ologger.core.web.jsonplugin.JSONUtil;
import com.sinovatech.ologger.util.LogUtil;
import com.sinovatech.ologger.util.StringHelper;

public class OperationLog {

	private static final Log logger = LogFactory.getLog(OperationLog.class);

	public static final String SEPARATOR_VALUES = ",";//日志详细中多个value分隔
	public static final String SEPARATOR_KEYVALUE = "#";//日志详细中key、value分隔符
	public static final String SEPARATOR_PROPERTY = "&";//日志详细中不同属性的分隔分隔符
	public static final String SEPARATOR_GROUP = "|";//日志详细中不同组的分隔符

	private Serializable id;

	private Serializable userId;
	/**
	 *  用户名
	 */
	private String username;

	/**
	 * 操作名称 如"新增员工"、"日报汇算"、"删除请假单"
	 */
	private String operationName;

	/**
	 * 操作详细信息/条件 
	 * 详细信息由获取时通过统一格式化输出
	 * 推荐格式:以"#"分隔属性名和值,以"&"分隔不同属性,在获取时统一格式 如:姓名#张三&部门#市场部
	 */
	private StringBuilder operationDetails = new StringBuilder();

	/**
	 * 操作对象变量的集合 以JSON格式保存 
	 * 避免直接操作,可通过opcMap对其控制
	 */
	private String operationConditions;

	/**
	 * 操作条件Map 对应operationConditions 
	 * 不保存到数据库
	 */
	private Map<String, Object> opcMap = new HashMap<String, Object>();

	/**
	 * 方法参数JSON字符串(记录拦截方法(Ajax/service方法)的所有参数)
	 */
	private String conditionsJSON;

	/**
	 * 原始的operationDetail信息保存在此处，留在需要时候使用
	 */
	private String srcOperationDetails;

	/**
	 * 操作时间
	 */
	private Timestamp createTime = null;

	public Serializable getId() {
		return id;
	}

	public void setId(Serializable id) {
		this.id = id;
	}

	public Serializable getUserId() {
		return userId;
	}

	public void setUserId(Serializable userId) {
		this.userId = userId;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Timestamp getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Timestamp createTime) {
		this.createTime = createTime;
	}

	public String getOperationName() {
		return operationName;
	}

	public void setOperationName(String operationName) {
		this.operationName = operationName;
	}

	public String getOperationDetails() {
		return operationDetails.toString();
	}

	public StringBuilder getOperationDetailsBuilder() {
		return operationDetails;
	}

	public void setOperationDetails(String operationDetails) {
		this.operationDetails = new StringBuilder(operationDetails);
	}

	public StringBuilder appendOperationDetails(String operationDetails) {
		return this.operationDetails.append(operationDetails);
	}

	public String getOperationConditions() {
		return operationConditions;
	}

	public String getSrcOperationDetails() {
		return srcOperationDetails;
	}

	public void setSrcOperationDetails(String srcOperationDetails) {
		this.srcOperationDetails = srcOperationDetails;
	}

	/**
	 * 该方法为Hibernate填充时使用 若要设置operationConditions(操作条件,可直接调用addOperationConditions)
	 * @see OperationLogVO.addOperationConditions 方法
	 * @param operationConditions
	 */
	@SuppressWarnings("unchecked")
	@Deprecated()
	public void setOperationConditions(String operationConditions) {
		this.operationConditions = operationConditions;
		if (!StringHelper.isEmpty(this.operationConditions)) {
			try {
				this.opcMap.putAll((Map<? extends String, ? extends Object>) JSONUtil.deserialize(operationConditions));
			} catch (JSONException e) {
				logger.error(LogUtil.stackTraceToString(e));
			}
		} else {
			this.opcMap.clear();
		}
	}

	public void addOperationConditions(String key, Object value) {
		this.opcMap.put(key, value);
	}

	public void flushOperationConditions() {
		if (this.opcMap.size() > 0) {
			try {
				this.operationConditions = JSONUtil.serialize(this.opcMap);
			} catch (JSONException e) {
				logger.error(LogUtil.stackTraceToString(e));
			}
		}
	}

	public String getConditionsJSON() {
		return conditionsJSON;
	}

	public void setConditionsJSON(String conditionsJSON) {
		this.conditionsJSON = conditionsJSON;
	}

	public Map<String, Object> getOpcMap() {
		return opcMap;
	}

}
